package com.winspread.mvvm.flowbus

import androidx.lifecycle.LiveData
import androidx.lifecycle.asLiveData
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import java.util.concurrent.ConcurrentHashMap
/**
 *Author: Amin
 *Data: 2022/1/24 14:14
 *
 *Description:
 *
 */
object SharedFlowBus {

    private var events = ConcurrentHashMap<Any, MutableSharedFlow<Any>>()

    private var stickyEvents = ConcurrentHashMap<Any, MutableSharedFlow<Any>>()

    /**
     * 发送消息
     *
     * 例：SharedFlowBus.with(objectKey: Class<T>).tryEmit(value: T)
     *
     * @param objectKey Class<T>
     * @return MutableSharedFlow<T>
     */
    fun <T> with(objectKey: Class<T>): MutableSharedFlow<T> {
        if (!events.containsKey(objectKey)) {
            events[objectKey] = MutableSharedFlow(0, 1, BufferOverflow.DROP_OLDEST)
        }
        return events[objectKey] as MutableSharedFlow<T>
    }


    /**
     * 发送粘性消息
     * 例：SharedFlowBus.withSticky(objectKey: Class<T>).tryEmit(value: T)
     *
     * @param objectKey Class<T>
     * @return MutableSharedFlow<T>
     */

    fun <T> withSticky(objectKey: Class<T>): MutableSharedFlow<T> {
        if (!stickyEvents.containsKey(objectKey)) {
            stickyEvents[objectKey] = MutableSharedFlow(1, 1, BufferOverflow.DROP_OLDEST)
        }
        return stickyEvents[objectKey] as MutableSharedFlow<T>
    }

    /**
     *  订阅消息
     *例如： SharedFlowBus.on(objectKey: Class<T>).observe(owner){ it ->
     *           println(it)
     *      }
     *
     *
     * @param objectKey Class<T>
     * @return SharedFlow<T>
     */

    fun <T> on(objectKey: Class<T>): LiveData<T> {
        return with(objectKey).asLiveData()
    }



    /**
     * 订阅粘性消息
     *
     *例如： SharedFlowBus.onSticky(objectKey: Class<T>).observe(owner){ it ->
     *            println(it)
     *      }
     *
     * @param objectKey Class<T>
     * @return SharedFlow<T>
     */

    fun <T> onSticky(objectKey: Class<T>): LiveData<T> {
        return withSticky(objectKey).asLiveData()
    }


}